#include "../../config.h"

#include "connection.h"

namespace gpyp {
namespace conf {

//========================
// PropertyConnection
void PropertyConnection::static_on_notify(GObject    */*gobject*/,
                                          GParamSpec *pspec,
                                          gpointer    user_data) {
  PropertyConnection *pc = (PropertyConnection *)user_data;
  if (pc->name_ == pspec->name) pc->on_changed();
}
void
PropertyConnection::static_on_changed(GtkTextBuffer */*textbuffer*/,
                                      gpointer       user_data) {
  PropertyConnection *pc = (PropertyConnection *)user_data;
  pc->on_changed();
}
void PropertyConnection::static_on_destroy(GtkObject */*gobject*/,
                                           gpointer   user_data) {
  PropertyConnection *pc = (PropertyConnection *)user_data;
  pc->on_destroy();
}

void PropertyConnection::on_changed() {
  signal_changed_(*this);
}
void PropertyConnection::on_destroy() {
  disconnect(&PropertyConnection::connection_notify_);
  disconnect(&PropertyConnection::connection_signal_);
  disconnect(&PropertyConnection::connection_destroy_);
  obj_ = NULL;
  signal_destroy_(*this);
}

PropertyConnection::PropertyConnection(GObject *obj, const char *name) :
  obj_               (obj),
  name_              (name),
  writable_          (false),
  value_type_        (0),
  connection_notify_ (0),
  connection_signal_ (0),
  connection_destroy_(0),
  unref_             (false)
{
  GParamSpec *spec =
    g_object_class_find_property(G_OBJECT_GET_CLASS(obj), name);
  writable_   = (spec->flags & G_PARAM_WRITABLE) != 0;
  value_type_ = spec->value_type;

  connection_notify_ =
    g_signal_connect(obj_, "notify",
                     G_CALLBACK(PropertyConnection::static_on_notify),
                     this);
  if (GTK_IS_OBJECT(obj)) {
    connection_destroy_ =
      g_signal_connect(obj_, "destroy",
                       G_CALLBACK(PropertyConnection::static_on_destroy),
                       this);
  } else {
    g_object_ref(obj_);
    unref_ = true;
  }
}
PropertyConnection::PropertyConnection(GtkTextBuffer *textbuffer) :
  obj_               (G_OBJECT(textbuffer)),
  name_              ("text"),
  writable_          (true),
  value_type_        (G_TYPE_STRING),
  connection_notify_ (0),
  connection_signal_ (0),
  connection_destroy_(0),
  unref_             (true)
{
  connection_signal_ =
    g_signal_connect(obj_, "changed",
                     G_CALLBACK(PropertyConnection::static_on_changed),
                     this);
  g_object_ref(obj_);
}
PropertyConnection::~PropertyConnection() {
  if (obj_) {
    disconnect(&PropertyConnection::connection_notify_);
    disconnect(&PropertyConnection::connection_signal_);
    disconnect(&PropertyConnection::connection_destroy_);
    if (unref_) g_object_unref(obj_);
  }
}

}/*conf*/
}/*gpyp*/
